package com.lk.device.service.impl;

import com.lk.base.mysql.domain.TblDevices;
import com.lk.base.mysql.domain.TblWrjData;
import com.lk.base.mysql.repository.TblDevicesRepository;
import com.lk.base.mysql.repository.TblWrjDataRepository;
import com.lk.base.utils.DateUtil;
import com.lk.base.utils.ResultUtil;
import com.lk.device.dto.DeviceDTO;
import com.lk.device.service.DevicesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;

@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DevicesServiceImpl implements DevicesService {

    @Autowired
    private TblDevicesRepository tblDevicesRepository;

    @Autowired
    private TblWrjDataRepository tblWrjDataRepository;

    @Override
    public Object selectAll(DeviceDTO dto, Pageable pageable) {
        Page page = tblDevicesRepository.findAll(new Spec(dto), pageable);

        Map<String,Object> map = new HashMap<>();
        map.put("content", page.getContent());
        map.put("totalElements", page.getTotalElements());
        return map;
    }

    @Override
    public Object selectAll(DeviceDTO dto) {
        List<TblDevices> all = tblDevicesRepository.findAll();

        return all;
    }

    @Override
    public Object selectByType(DeviceDTO dto) {
        List<TblDevices> all = tblDevicesRepository.findByDeviceType(dto.getDeviceType());

        return all;
    }

    @Override
    public Object selectOne(DeviceDTO dto) {

        List<TblDevices> all = tblDevicesRepository.findByDeviceType(dto.getDeviceType());

        return all!= null &&all.size() > 0? all.get(0) : new TblDevices();
    }

    @Override
    public Object sendWrjData(TblWrjData dto) {
        String datas = dto.getDatas();
        String now = DateUtil.getCurrentTime();
        if(datas!= null && datas.length()>0){
            List<TblWrjData> twdList = new ArrayList<>();
            String[] arr = datas.split(";");
            for (int i = 0; i < arr.length; i++) {
                String s = arr[i];
                String[] tmp = s.split(",");
                TblWrjData twd = new TblWrjData();
                twd.setId(UUID.randomUUID().toString().replaceAll("-",""));
                twd.setCreateTime(now);
                twd.setLongitude(tmp[0]);
                twd.setLatitude(tmp[1]);
                twd.setAltitude(tmp[2]);
                twd.setDeviceId(dto.getDeviceId());
                twdList.add(twd);
            }
            tblWrjDataRepository.saveAll(twdList);
        }

        return ResultUtil.Ok("推送成功");
    }

    @Override
    public void save(TblDevices dto) {
        if(dto.getId()== null){
            dto.setId(UUID.randomUUID().toString());
        }
        tblDevicesRepository.save(dto);
    }

    @Override
    public void deleteDevice(DeviceDTO dto) {
        String ids = dto.getIds();
        String[] arr = ids.split(",");
        for (int i = 0; i < arr.length; i++) {
            String id = arr[i];
            tblDevicesRepository.deleteById(id);
        }

    }

    @Override
    public void saveDeviceStatus(TblDevices dto) {
        Optional<TblDevices> byId = tblDevicesRepository.findById(dto.getId());
        TblDevices tblDevices = byId.get();
        tblDevices.setStatus(dto.getStatus());
        tblDevicesRepository.save(tblDevices);
    }


    class Spec implements Specification<TblDevices> {

        private DeviceDTO dto;

        public Spec(DeviceDTO dto){
            this.dto = dto;
        }

        @Override
        public Predicate toPredicate(Root<TblDevices> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {

            List<Predicate> list = new ArrayList<Predicate>();

            if(!ObjectUtils.isEmpty(dto.getName())){
                /**
                 * 模糊
                 */
                list.add(cb.like(root.get("name").as(String.class),"%"+dto.getName()+"%"));
            }

            if(!ObjectUtils.isEmpty(dto.getCreateTime())){
                /**
                 * 模糊
                 */
                list.add(cb.like(root.get("createTime").as(String.class),"%"+dto.getCreateTime()+"%"));
            }
            if(!ObjectUtils.isEmpty(dto.getStatus())){
                /**
                 * 模糊
                 */
                list.add(cb.like(root.get("status").as(String.class),"%"+dto.getStatus()+"%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return cb.and(list.toArray(p));
        }
    }
}
